create or replace
PROCEDURE SP_PROCESAR_BILLETE_BONO(
      p_daFechaVenta in timestamp,
      p_vaCantidad in number,
      p_coClientePersona in number, --84842
      p_coVenta in number, --8643652 8643661 8643640 8643649
      p_vaPrecioUnitario in number,
      p_vaPrecioVenta in out number,
      p_coCodeEstacion in varchar2,
      p_deMensaje out varchar2      
)AS 

coPromocionBono number(19);
coTipoBono number(19);
nuDiasVencimiento number(2);
vaCantidadBonos number(2);
daFechaVencimiento timestamp;
deTipoBono varchar2(30);
i number := 0;
contadorBonos number;
coBonoCliente number(19);
vaMontoMinimoVenta number(10,2);
vaMontoBono number(10,2);
vaCantidad number(10,2);
vaMontoMinimo number(10,2);
deMonto varchar2(20);

stUsoBono char(1) := 'N';
stGanoBono char(1) := 'N';
stTieneBonosAcumulados char(1) := 'N';
stHayPromocion char(1) := 'N';

cursor cpromociones is 
    select
        pb.id as coPromocionBono, 
        pb.de_nombre as deNombrePromocion,
        pb.va_monto_minimo as vaMontoMinimo, 
        pb.st_caducar_bono as stCaducarBono,
        tb.id as coTipoBono,
        tb.de_tipo_bono as deTipoBono,
        tb.va_monto as vamontobono,
        tb.nu_dias_vencimiento as nudiasvencimiento
    from clpb_promocion_bono pb 
      join clpd_tipo_bono tb on pb.co_tipo_bono = tb.id
      join clpr_promocion_estacion pe on pb.id = pe.co_promocion_bono
      join clpb_estacion est on pe.co_estacion = est.id    
    where to_date(to_char(p_dafechaventa, 'dd/MM/yyyy'), 'dd/MM/yyyy') between  
          to_date(to_char(pb.da_inicio_vigencia, 'dd/MM/yyyy'), 'dd/MM/yyyy') and 
          to_date(to_char(pb.da_fin_vigencia, 'dd/MM/yyyy'), 'dd/MM/yyyy')
      and trim(est.co_codigo_cofide) = trim(p_coCodeEstacion)
      and pb.st_promocion_bono = 'Y' and pb.st_bloqueado = 'N'
      and tb.st_tipo_bono = 'Y' and pe.st_promocion_estacion = 'Y'
      and est.st_estacion = 'Y';
      
cursor cbonos is
    select pb.id as coPromocionBono, 
        pb.da_inicio_vigencia as daInicioVigencia, 
        pb.da_fin_vigencia as daFinVigencia,
        pb.st_caducar_bono as stcaducarbono, 
        pb.va_monto_minimo as vaMontoMinimoVenta,
        bcp.id as coBonoCliente, 
        tb.va_monto as vaMontoBono         
    from clpm_bono_cliente_persona bcp 
      join clpb_cliente_persona cp on bcp.co_cliente_persona = cp.id
      join clpb_promocion_bono pb on bcp.co_promocion_bono = pb.id
      join clpd_tipo_bono tb on bcp.co_tipo_bono = tb.id
      join clpr_promocion_estacion pe on pb.id = pe.co_promocion_bono
      join clpb_estacion est on pe.co_estacion = est.id
    where 
        bcp.co_cliente_persona = p_coclientepersona and 
        trim(est.co_codigo_cofide) = trim(p_coCodeEstacion) and 
        to_date(to_char(bcp.da_fecha_vencimiento, 'dd/MM/yyyy'), 'dd/MM/yyyy') >= 
        to_date(to_char(p_daFechaVenta, 'dd/MM/yyyy'), 'dd/MM/yyyy')
        and bcp.st_usado = 'N' and bcp.st_bono_cliente_persona = 'Y' and pb.st_bloqueado = 'N'
        and pe.st_promocion_estacion = 'Y' and est.st_estacion = 'Y'
    order by bcp.da_fecha_vencimiento asc;
BEGIN
  
  p_deMensaje := '';
  contadorBonos := 0;
  dbms_output.put_line('p_vaPrecioVenta ' || p_vaPrecioVenta);
  for bono in cbonos loop
      dbms_output.put_line('tiene bonos ');     
      if (bono.stCaducarBono = 'N' and coBonoCliente is null) then       
          dbms_output.put_line('bonos no caducos');
          if (coBonoCliente is null) then
              dbms_output.put_line('verificando si aplica el bono');
              if (p_vaPrecioVenta >= bono.vaMontoMinimoVenta) then    
                
                dbms_output.put_line('marcando el bono como usado');                
                update clpm_bono_cliente_persona 
                set st_usado = 'Y', co_venta_consumo = p_coVenta, 
                    co_usuario_modificador = 'clubpgn', da_fecha_modificacion = sysdate 
                where id = bono.coBonoCliente;                 
                coBonoCliente := bono.coBonoCliente;
                vaMontoBono := bono.vaMontoBono;
                p_vaPrecioVenta := p_vaPrecioVenta - vaMontoBono;
                stUsoBono := 'Y';
              else
                dbms_output.put_line('no aplico el bono');
                contadorBonos := contadorBonos + 1;
              end if;          
          else
            dbms_output.put_line('no se usa el bono');
            contadorBonos := contadorBonos + 1;
          end if;        
      elsif (to_date(to_char(p_dafechaventa, 'dd/MM/yyyy'), 'dd/MM/yyyy') <= 
              to_date(to_char(bono.daFinVigencia, 'dd/MM/yyyy'), 'dd/MM/yyyy') and 
              to_date(to_char(p_dafechaventa, 'dd/MM/yyyy'), 'dd/MM/yyyy') >= 
              to_date(to_char(bono.daInicioVigencia, 'dd/MM/yyyy'), 'dd/MM/yyyy') and 
              coBonoCliente is null) then
          
          dbms_output.put_line('Se usan bonos caducos ');
          dbms_output.put_line('p_dafechaventa = '|| to_char(p_dafechaventa, 'dd/MM/yyyy'));
          dbms_output.put_line('bono.daFinVigencia = '|| to_char(bono.daFinVigencia, 'dd/MM/yyyy'));
          dbms_output.put_line('bono.daInicioVigencia = '|| to_char(bono.daInicioVigencia, 'dd/MM/yyyy'));    
             if (p_vaPrecioVenta >= bono.vaMontoMinimoVenta) then    
                
                update clpm_bono_cliente_persona 
                set st_usado = 'Y', co_venta_consumo = p_coVenta, 
                    co_usuario_modificador = 'clubpgn', da_fecha_modificacion = sysdate 
                where id = bono.coBonoCliente;                 
                coBonoCliente := bono.coBonoCliente;
                vaMontoBono := bono.vaMontoBono;
                p_vaPrecioVenta := p_vaPrecioVenta - vaMontoBono;
                stUsoBono := 'Y';
              else
                dbms_output.put_line('no aplico el bono');
                contadorBonos := contadorBonos + 1;
              end if;              
      end if;      
  end loop;  
  
  dbms_output.put_line('contadorBonos ' || contadorBonos);
  if (contadorBonos > 0) then
    stTieneBonosAcumulados := 'Y';
  end if;
  
  vaCantidad := p_vaCantidad;
  p_vaPrecioVenta := round(p_vaPrecioVenta, 2);
  dbms_output.put_line('p_vaPrecioVenta ' || p_vaPrecioVenta);
  if (coBonoCliente is not null) then  
    deMonto := replace('' || vaMontoBono, ',', '.');
    p_deMensaje := p_deMensaje || 'Ha utilizado S/.' || deMonto 
            || ' PGN. Por consumo de GNV debe pagar S/.';
    
    deMonto := replace('' || p_vaPrecioVenta, ',', '.');       
    p_deMensaje := p_deMensaje || deMonto || '.';  
    vaCantidad := p_vaPrecioVenta / p_vaPrecioUnitario;
  end if;
  
  for promocion in cpromociones loop
    
    stHayPromocion := 'Y';
    coPromocionBono := promocion.coPromocionBono;
    coTipoBono := promocion.coTipoBono;
    nuDiasVencimiento := promocion.nuDiasVencimiento;
    vaMontoBono := promocion.vaMontoBono;
    vaMontoMinimo := promocion.vaMontoMinimo;
    
    for rango in (
          select id as coRangpoPromocion,
              va_consumo_inicio as vaConsumoInicio,
              va_consumo_fin as vaConsumoFin,
              va_cantidad as vaCantidad
          from clpd_rango_promocion 
          where co_promocion_bono = coPromocionBono 
            and va_consumo_inicio <= vaCantidad 
            and (va_consumo_fin > p_vaCantidad or (va_consumo_fin is null and st_es_rango_final = 'Y')) 
            and st_rango_promocion = 'Y') loop

      vaCantidadBonos := rango.vaCantidad;
      select (p_daFechaVenta + nuDiasVencimiento) into daFechaVencimiento from dual; 
      
      while i < vaCantidadBonos
      loop
        stGanoBono := 'Y';
        insert into clpm_bono_cliente_persona(
                  id, co_cliente_persona, va_cantidad, co_promocion_bono,
                  co_tipo_bono, da_fecha_vencimiento, st_tipo_generacion, 
                  co_venta_generacion, st_usado, st_bono_cliente_persona, 
                  co_usuario_creador, da_fecha_creacion, da_fecha_generacion)
        values(
            SEQ_BONO_CLIENTE.nextval, p_coClientePersona, 1, coPromocionBono, 
            coTipoBono, daFechaVencimiento, 'W', 
            p_coVenta, 'N', 'Y', 
            'clubpgn', sysdate, sysdate);
        i := i + 1;  
      end loop;    
            
      if (p_deMensaje is null or length(p_deMensaje) <= 0) then
        deMonto := replace('' || (vaCantidadBonos * vaMontoBono), ',', '.');   
        p_deMensaje := p_deMensaje || 'Ha ganado S/.' || deMonto;
        p_deMensaje := p_deMensaje || ' PGN. Utilizalo en tu siguiente consumo.';          
      else
        deMonto := replace('' || (vaCantidadBonos * vaMontoBono), ',', '.');   
        p_deMensaje := p_deMensaje || ' Y ademas, ha ganado S/.' || deMonto;
        p_deMensaje := p_deMensaje || ' PGN.';        
      end if;
      
    end loop; --rangos
    
  end loop; --cpromociones
  
  dbms_output.put_line('p_deMensaje ' || p_deMensaje);
  dbms_output.put_line('stUsoBono ' || stUsoBono);
  dbms_output.put_line('stTieneBonosAcumulados ' || stTieneBonosAcumulados);
  dbms_output.put_line('stGanoBono ' || stGanoBono);
  dbms_output.put_line('stHayPromocion ' || stHayPromocion);
  if (stUsoBono = 'N' and stTieneBonosAcumulados = 'Y' and coBonoCliente is null) then
    deMonto := replace('' || (vaMontoMinimo), ',', '.');  
    p_deMensaje := p_deMensaje || ' Recuerda que el consumo minimo es S/.' || deMonto;
    
    deMonto := replace('' || (vaMontoBono), ',', '.');  
     p_deMensaje := p_deMensaje || ' para poder utilizar los S/.' || deMonto || ' PGN.';
  end if;
  
  if (p_deMensaje is not null and length(p_deMensaje) > 0) then
    p_deMensaje := p_deMensaje || rpad(' ', 39, '-') || ' ';
  end if;  
  
END SP_PROCESAR_BILLETE_BONO;